package com.lzh.compiler.parceler;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.IntentParams;
import ohos.agp.components.Component;
import ohos.app.Context;
import ohos.bluetooth.BluetoothDeviceClass;

import java.security.SecureRandom;

/**
 * 用于配合BundleBuilder生成类进行使用的启动器。可用于进行Activity/Service/BroadcastReceiver启动。
 * @author haoge on 2017/12/26.
 */
public class IntentLauncher {
    private ActivityResultCallback callback;
    private int requestCode = -1;
    private IntentParams options;
    private IntentParams bundle;
    private Class<?> target;
    private Intent extra;

    private static SecureRandom sCodeGenerator;

    private IntentLauncher(IntentParams bundle, Class<?> target) {
        this.bundle = bundle;
        this.target = target;
    }

    /**
     * 创建一个Intent启动器。此启动器关联此Builder类。
     *
     * <p>此Builder实例用于提供传输的Bundle数据。以及所关联的目标类：{@link IBundleBuilder#getTarget()}。
     *
     * <p>目前此此启动器所支持的关联目标类包括Activity、Service以及BroadcastReceiver的子类。
     *
     * @param builder 提供数据的Builder
     * @return Intent
     */
    static IntentLauncher create(IBundleBuilder builder) {
        return new IntentLauncher(builder.build(), builder.getTarget());
    }

    static IntentLauncher create(IntentParams bundle, Class<?> target) {
        return new IntentLauncher(bundle, target);
    }

    /**
     * 设置startActivity时所需要的requestCode。对应{@link (Intent, int)}
     *
     * @param requestCode 请求码
     * @return setRequestCode
     */
    public IntentLauncher setRequestCode(int requestCode) {
        this.requestCode = requestCode;
        return this;
    }

    /**
     * 设置在onActivityResult时使用的回调。
     * @param callback ActivityResultCallback
     * @return Intent
     */
    public IntentLauncher setResultCallback(ActivityResultCallback callback) {
        this.callback = callback;
        return this;
    }

    /**
     * 设置startActivity时所需要的options参数。对应{@link
     * @param options IntentParams
     * @return IntentLauncher
     */
    public IntentLauncher setOptions(IntentParams options) {
        this.options = options;
        return this;
    }

    /**
     * 设置Intent镜像。在进行Intent创建时。若设置的extra Intent不为null。则将对此intent实例进行clone并替换Classname提供使用
     * @param intent Intent镜像
     * @return IntentLauncher
     */
    public IntentLauncher setExtra(Intent intent) {
        this.extra = intent;
        return this;
    }

    /**
     * 根据之前配置的数据，获取所需要的Intent实例。
     * @param context Context
     * @return intent
     */
    public Intent getIntent(Context context) {
        if (context == null) {
            return null;
        }
        Class<?> target = this.target;
        if (!Ability.class.isAssignableFrom(target)
                && !BluetoothDeviceClass.Service.class.isAssignableFrom(target)) {
            return null;
        }
        Intent intent = null;
        if (extra != null) {
            intent = new Intent(extra);
            extra = null;
        } else {
        }
        return intent;
    }

    public void start(Component.ClickedListener context) {
        if (context == null) {
            return;
        }
        Intent intent = new Intent();
        intent.getClass();
        Class<?> target = this.target;

        if (Ability.class.isAssignableFrom(target)) {
            startActivity((Context) context, intent);
        }
    }

    private void startActivity(Context context, Intent intent) {
        if (context instanceof Ability) {
            if (callback != null && requestCode == -1) {
                requestCode = sCodeGenerator.nextInt(0x0000FFFF);
            }
            Ability activity = (Ability) context;
            if (options != null) {
                activity.startAbilityForResult(intent, requestCode);
            } else {
                activity.startAbilityForResult(intent, requestCode);
            }
            ActivityResultDispatcher.get().bindRequestArgs(activity, requestCode, callback);
        } else {
            intent.setFlags(Intent.FLAG_ABILITY_NEW_MISSION);
            context.stopAbility(intent);
        }
    }
    static {
        sCodeGenerator = new SecureRandom();
    }
}
